home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / ksubr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  6.1 KB  |  254 lines

  1. /* Machine or compiler-dependent portions of kernel
  2.  * Turbo-C version for PC
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include <stdio.h>
  7. #include <dos.h>
  8. #include "global.h"
  9. #include "proc.h"
  10. #include "pc.h"
  11. #include "commands.h"
  12.  
  13. static int near chkintstk __ARGS((void));
  14.  
  15. #ifdef PROCLOG
  16. int stkutil __ARGS((struct proc *pp));
  17. #else
  18. static int near stkutil __ARGS((struct proc *pp));
  19. #endif
  20.  
  21. static char * near Taskers[] = {
  22.     "",
  23.     "DoubleDos",
  24.     "DesqView",
  25.     "Windows3",
  26. };
  27.  
  28. /* Template for contents of jmp_buf in Turbo C */
  29. struct env {
  30.     unsigned    sp;
  31.     unsigned    ss;
  32.     unsigned    flag;
  33.     unsigned    cs;
  34.     unsigned    ip;
  35.     unsigned    bp;
  36.     unsigned    di;
  37.     unsigned    es;
  38.     unsigned    si;
  39.     unsigned    ds;
  40. };
  41.  
  42. void
  43. kinit()
  44. {
  45.     int i;
  46.  
  47.     /* Initialize interrupt stack for high-water-mark checking */
  48.     for(i = 0; i < 512; i++)
  49.         Intstk[i] = STACKPAT;
  50. }
  51.  
  52. /* Print process table info
  53.  * Since things can change while ps is running, the ready proceses are
  54.  * displayed last. This is because an interrupt can make a process ready,
  55.  * but a ready process won't spontaneously become unready. Therefore a
  56.  * process that changes during ps may show up twice, but this is better
  57.  * than not having it showing up at all.
  58.  */
  59. int
  60. ps(int argc,char *argv[],void *p)
  61. {
  62.     struct proc *pp;
  63.     struct env *ep;
  64. //    int i;
  65.  
  66.     tprintf("Stack %x max intstk %u",getss(),chkintstk());
  67.  
  68.     if(Mtasker != 0)
  69.         tprintf(" Running under %s",Taskers[Mtasker]);
  70.  
  71.     tputs("\nPID       SP        stksize   maxstk    event     fl  in  out  name\n");
  72.  
  73.     for(pp = Susptab; pp != NULLPROC; pp = pp->next) {
  74.         ep = (struct env *)&pp->env;
  75.         tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %3d %3d  %s\n",
  76.          ptol(pp),
  77.          ptol(MK_FP(ep->ss,ep->sp)),
  78.          pp->stksize,
  79.          stkutil(pp),
  80.          ptol(pp->event),
  81.          pp->i_state ? 'I' : ' ',
  82.          (pp->state & WAITING) ? 'W' : ' ',
  83.          (pp->state & SUSPEND) ? 'S' : ' ',
  84.          pp->input, pp->output,
  85.          pp->name);
  86.     }
  87.         for(pp = Waittab;pp != NULLPROC;pp = pp->next){
  88.             ep = (struct env *)&pp->env;
  89.             tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %2d %2d  %s\n",
  90.              ptol(pp),ptol(MK_FP(ep->ss,ep->sp)),pp->stksize,stkutil(pp),
  91.              ptol(pp->event),
  92.              pp->i_state ? 'I' : ' ',
  93.              (pp->state & WAITING) ? 'W' : ' ',
  94.              (pp->state & SUSPEND) ? 'S' : ' ',
  95.              pp->input,pp->output,
  96.              pp->name);
  97.         
  98.     }
  99.     for(pp = Rdytab; pp != NULLPROC; pp = pp->next) {
  100.         ep = (struct env *)&pp->env;
  101.         tprintf("%-10lx%-10lx%-10u%-10u          %c%c%c %2d %2d  %s\n",
  102.          ptol(pp),ptol(MK_FP(ep->ss,ep->sp)),pp->stksize,stkutil(pp),
  103.          pp->i_state ? 'I' : ' ',
  104.          (pp->state & WAITING) ? 'W' : ' ',
  105.          (pp->state & SUSPEND) ? 'S' : ' ',
  106.          pp->input,pp->output,
  107.          pp->name);
  108.     }
  109.     if(Curproc != NULLPROC){
  110.         ep = (struct env *)&Curproc->env;
  111.         tprintf("%-10lx%-10lx%-10u%-10u          %c   %2d %2d  %s\n",
  112.          ptol(Curproc),ptol(MK_FP(ep->ss,ep->sp)),Curproc->stksize,
  113.          stkutil(Curproc),
  114.          Curproc->i_state ? 'I' : ' ',
  115.          Curproc->input,Curproc->output,
  116.          Curproc->name);
  117.     }
  118.     return 0;
  119. }
  120.  
  121. #ifdef PROCLOG
  122. int
  123. #else
  124. static int near
  125. #endif
  126. stkutil(struct proc *pp)
  127. {
  128.     int16 *sp;
  129.     unsigned int i = pp->stksize;
  130.  
  131.     for(sp = pp->stack; *sp == STACKPAT && sp < (pp->stack + pp->stksize); sp++)
  132.         i--;
  133.  
  134.     return (int) i;
  135. }
  136.  
  137. /* Return number of used words in interrupt stack. Note hardwired value
  138.  * for stack size; this is also found in the various .asm files
  139.  */
  140. static int near
  141. chkintstk()
  142. {
  143.     int i;
  144.     int16 *cp;
  145.  
  146.     for(i = 512, cp = Intstk; i != 0 && *cp == STACKPAT; cp++)
  147.         i--;
  148.  
  149.     return i;
  150. }
  151.  
  152. /* Verify that stack pointer for current process is within legal limits;
  153.  * also check that no one has dereferenced a null pointer
  154.  */
  155. void
  156. chkstk()
  157. {
  158.     struct proc *Curproct = Curproc;
  159.  
  160.     int16 *sbase, *stop, *sp = MK_FP(_SS,_SP);
  161. #ifdef XXX
  162.     int Nokeys = 0;
  163. #endif
  164.  
  165.     if(_SS == _DS){
  166.         /* Probably in interrupt context */
  167.         return;
  168.     }
  169.  
  170.     if((sbase = Curproct->stack) == NULL)
  171.         return;    /* Main task -- too hard to check */
  172.  
  173.     stop = sbase + Curproct->stksize;
  174.  
  175.     if(sp < sbase || sp >= stop){
  176.         printf("\nStack violation, process %s\n",Curproct->name);
  177.         printf("SP=%lx, legal stack range [%lx,%lx] ",
  178.             ptol(sp),ptol(sbase),ptol(stop));
  179.         printf("stksize=%u, maxstk=%u\n\n",
  180.             Curproct->stksize,stkutil(Curproct));
  181.         iostop();
  182.         exit(254);
  183.     } 
  184. }
  185.  
  186. /* Machine-dependent initialization of a task */
  187. void
  188. psetup(pp,iarg,parg1,parg2,pc)
  189. struct proc *pp;    /* Pointer to task structure */
  190. int iarg;            /* Generic integer arg */
  191. void *parg1;        /* Generic pointer arg #1 */
  192. void *parg2;        /* Generic pointer arg #2 */
  193. void (*pc)();        /* Initial execution address */
  194. {
  195.     register struct env *ep;
  196.  
  197.     /* Set up stack to make it appear as if the user's function was called
  198.      * by killself() with the specified arguments. When the user returns,
  199.      * killself() automatically cleans up.
  200.      *
  201.      * First, push args on stack in reverse order, simulating what C
  202.      * does just before it calls a function.
  203.      */
  204.     unsigned *stktop = ((unsigned *)pp->stack + pp->stksize);
  205.  
  206. #ifdef    LARGEDATA
  207.     *--stktop = FP_SEG(parg2);
  208. #endif
  209.     *--stktop = FP_OFF(parg2);
  210. #ifdef    LARGEDATA
  211.     *--stktop = FP_SEG(parg1);
  212. #endif
  213.     *--stktop = FP_OFF(parg1);
  214.     *--stktop = iarg;
  215.  
  216.     /* Now push the entry address of killself(), simulating the call to
  217.      * the user function.
  218.      */
  219. #ifdef    LARGECODE
  220.     *--stktop = FP_SEG(killself);
  221. #endif
  222.     *--stktop = FP_OFF(killself);
  223.  
  224.     /* Set up task environment. Note that for Turbo-C, the setjmp
  225.      * sets the interrupt enable flag in the environment so that
  226.      * interrupts will be enabled when the task runs for the first time.
  227.      * Note that this requires newproc() to be called with interrupts
  228.      * enabled!
  229.      */
  230.     setjmp(pp->env);
  231.  
  232.     ep = (struct env *)&pp->env;
  233.     ep->ss = FP_SEG(stktop);
  234.     ep->sp = FP_OFF(stktop);
  235.     ep->cs = FP_SEG(pc);    /* Doesn't hurt in small model */
  236.     ep->ip = FP_OFF(pc);
  237.  
  238.     /* Task initially runs with interrupts on */
  239.     pp->i_state = 1;
  240. }
  241.  
  242. unsigned
  243. phash(void *event)
  244. {
  245.  
  246.     /* Fold the two halves of the pointer */
  247.     unsigned x = FP_SEG(event) ^ FP_OFF(event);
  248.  
  249.     /* If PHASH is a power of two, this will simply mask off the
  250.      * higher order bits
  251.      */
  252.     return (x % PHASH);
  253. }
  254.